
    
    #include "ch.h"
#include "hal.h"
#include <AudioClass.h>
#include "UsbAudioCfg.h"

static const uint8_t audio_device_descriptor_data[18] = {
		  USB_DESC_DEVICE       (0x0200,        /* bcdUSB (2.0).                    */
		                         0xEF,          /* bDeviceClass (Misc).             */
		                         0x02,          /* bDeviceSubClass.                 */
		                         0x01,          /* bDeviceProtocol.                 */
		                         0x40,          /* bMaxPacketSize.                  */
		                         0x2122,        /* idVendor (ST).                   */
		                         0x2b3a,        /* idProduct.                       */
		                         0x0200,        /* bcdDevice.                       */
		                         1,             /* iManufacturer.                   */
		                         2,             /* iProduct.                        */
		                         3,             /* iSerialNumber.                   */
		                         1)             /* bNumConfigurations.              */
};


/*
 * Device Descriptor wrapper.
 */
static const USBDescriptor audio_device_descriptor = {
  sizeof audio_device_descriptor_data,
  audio_device_descriptor_data
};

/*
 * USB Device Qualifier Descriptor
 *
 */

static const uint8_t audio_device_qualifier_descriptor_data[10] = {
		USB_DESC_DEVICE_QUALIFIER (
						0x0200,
						0xEF,
						0x02,
						0x00,
						0x40,
						1)

};

static const USBDescriptor audio_device_qualifier_descriptor = {
  sizeof audio_device_qualifier_descriptor_data,
  audio_device_qualifier_descriptor_data
};


/*
*	These configuration descriptors are from freescale USB Stack 
*/

/*
 * USB Configuration Descriptor
 */
#define AUDIO_CONF_SIZE 127
static const uint8_t audio_configuration_descriptor_data[AUDIO_CONF_SIZE] = {
		/* Configuration Descriptor  size: 9*/

    /* Standard Configuration Descriptor */
    0x09,  					/* bLength(0x09) */
    0x02,                   /* bDescriptorType(0x02) */
    AUDIO_CONF_SIZE, 0x00, 	/* wTotalLength(127) */
    0x02,                   /* bNumInterfaces(0x02):
                                INTERFACE 0: AudioControl
                                INTERFACE 1: AudioStreaming */
    0x01,                   /* bConfigurationValue(0x01) */
    0x00,                   /* iConfiguration(0x00) */
    0xC0, 					/* bmAttributes(0xC0) */
    0xFA,                   /* bMaxPower(0xFA): 500mA */

    /* Standard Interface Association Descriptor */
    0x08,                                   /* bLength(0x08) */
    0x0B,   								/* bDescriptorType(0x0B) */
    0x00,                                   /* bFirstInterface(0x00) */
    0x02,                                   /* bInterfaceCount(0x02) */
    0x01,                                   /* bFunctionClass(0x01): AUDIO */
    0x00,                                   /* bFunctionSubClass(0x00) */
    0x20,                                   /* bFunctionProtocol(0x2000): 2.0 AF_VERSION_02_00 */
    0x00,                                   /* iFunction(0x00) */

    /******************** INTERFACE 0 ************************/
    /* AUDIO CONTROL Interface */
    /* Standard AC Interface Descriptor(4.7.1) */
    0x09,       /* bLength(0x09) */
    0x04,       /* bDescriptorType(0x04): INTERFACE */
    0x00,       /* bInterfaceNumber(0x00) */
    0x00,       /* bAlternateSetting(0x00) */
    0x00,       /* bNumEndpoints(0x00) */
    0x01,       /* bInterfaceClass(0x01): AUDIO */
    0x01,       /* bInterfaceSubClass(0x01): AUDIOCONTROL */
    0x20,       /* bInterfaceProtocol(0x20): IP 2.0 IP_VERSION_02_00 */
    0x00,       /* iInterface(0x07): Not Requested */

    /* Class-Specific AC Interface Header Descriptor(4.7.2) */
    0x09,       /* bLength(0x09) */
    0x24,       /* bDescriptorType(0x24): CS_INTERFACE */
    0x01,       /* bDescriptorSubType(0x01): HEADER */
    0x00, 0x02, /* bcdADC(0x0200): 2.0 */
    0x01,       /* bCategory(0x01): DESKTOP_SPEAKER */
    USB_DESC_WORD(46),
    0x00,       /* bmControls(0b00000000) */

    /* Clock Source Descriptor(4.7.2.1) */
    0x08,       /* bLength(0x08) */
    0x24,       /* bDescriptorType(0x24): CS_INTERFACE */
    0x0A,       /* bDescriptorSubType(0x0A): CLOCK_SOURCE */
    0x10,       /* bClockID(0x10): CLOCK_SOURCE_ID */
    0x01,       /* bmAttributes(0x01): internal fixed clock */
    0x07,       /* bmControls(0x07):
                        clock frequency control: 0b11 - host programmable;
                        clock validity control: 0b01 - host read only */
    0x00,       /* bAssocTerminal(0x00) */
    0x00,       /* iClockSource(0x01): Not requested */

    /* Input Terminal Descriptor(4.7.2.4) */
    0x11,       /* bLength(0x11): 17 */
    0x24,       /* bDescriptorType(0x24): CS_INTERFACE */
    0x02,       /* bDescriptorSubType(0x02): INPUT_TERMINAL */
    0x20,       /* bTerminalID(0x20): INPUT_TERMINAL_ID */
    0x01, 0x01, /* wTerminalType(0x0101): USB streaming */
    0x00,       /* bAssocTerminal(0x00) */
    0x10,       /* bCSourceID(0x10): CLOCK_SOURCE_ID */
    0x01,		/* bNrChannels(0x01) */
    0x00, 0x00, 0x00, 0x00, /* bmChannelConfig(0x00): Mono, no spatial location */
    0x00,       /* iChannelNames */
    0x00, 0x00, /* bmControls(0x0000) */
    0x00,       /* iTerminal(0x02): not requested */

    /* Output Terminal Descriptor(4.7.2.5) */
    0x0C,       /* bLength(12) */
    0x24,       /* bDescriptorType(0x24): CS_INTERFACE */
    0x03,       /* bDescriptorSubType(0x03): OUTPUT_TERMINAL */
    0x40,       /* bTerminalID(0x40) */
    0x01, 0x01, /* wTerminalType(0x0101): USB_STREAMING */
    0x00,       /* bAssocTerminal(0x00): no association */
    0x30,       /* bSourceID(0x30): FEATURE_UNIT_ID */
    0x10,       /* bCSourceID(0x10): CLOCK_SOURCE_ID */
    0x00, 0x00, /* bmControls(0x0000) */
    0x00,       /* iTerminal(0x00): Not Requested */
    /******************** INTERFACE 0 ************************/

    /******************** INTERFACE 1 ************************/
    /* AUDIO STREAMING Interface */
    /* Standard AS Interface Descriptor(4.9.1) */
    /* Interface 1, Alternate 0 */
    /* default alternate setting with 0 bandwidth */
    0x09,       /* bLength(9) */
    0x04,       /* bDescriptorType(0x04): INTERFACE */
    0x01,       /* bInterfaceNumber(0x01) */
    0x00,       /* bAlternateSetting(0x00) */
    0x01,       /* bNumEndpoints(0x00) */
    0x01,       /* bInterfaceClass(0x01): AUDIO */
    0x02,       /* bInterfaceSubClass(0x02): AUDIOSTREAMING */
    0x20,       /* bInterfaceProtocol(0x20): IP 2.0 */
    0x00,       /* iInterface */

    /* Standard AS Interface Descriptor(4.9.1) */
    /* INterface 1, Alternate 1 */
    /* alternate interface for data streaming */
    0x09,       /* bLength(9) */
    0x04,       /* bDescriptorType(0x04): INTERFACE */
    0x01,       /* bInterfaceNumber(0x01) */
    0x01,       /* bAlternateSetting(0x01) */
    0x00,       /* bNumEndpoints(0x01) */
    0x01,       /* bInterfaceClass(0x01): AUDIO */
    0x02,       /* bInterfaceSubClass(0x02): AUDIO_STREAMING */
    0x20,       /* bInterfaceProtocol(0x20): IP 2.0 */
    0x00,       /* iInterface */

    /* Class-Specific AS Interface Descriptor(4.9.2) */
    0x10,       /* bLength(16) */
    0x24,       /* bDescriptorType(0x024): CS_INTERFACE */
    0x01,       /* bDescriptorSubType(0x01): AS_GENERAL */
    0x20,       /* bTerminalLink(0x20): INPUT_TERMINAL_ID */
    0x00,       /* bmControls(0x00) */
    0x01,       /* bFormatType(0x01): FORMAT_TYPE_I */
    0x01, 0x00, 0x00, 0x00, /* bmFormats(0x00000001): PCM */
    0x02,       /* bNrChannels(0x02): NB_CHANNELS */
    0x03, 0x00, 0x00, 0x00, /* bmChannelCOnfig(0x00000003) */
    0x00,       /* iChannelNames(0x00): None */

    /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */
    0x06,       /* bLength(6) */
    0x24,       /* bDescriptorType(0x24): CS_INTERFACE */
    0x02,       /* bDescriptorSubtype(0x02): FORMAT_TYPE */
    0x01,       /* bFormatType(0x01): FORMAT_TYPE_I */
    0x04,       /* bSubSlotSize(0x01) */
    0x18,       /* bBitResolution(0x18): 8 bits per sample */

    /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */
    0x07,       /* bLength(7) */
    0x05,       /* bDescriptorType(0x05): ENDPOINT_DESCRIPTOR */
    0x01,   	/* bEndpointAddress(0x01) */
    0x0D,       /* bmAttributes(0x02): iso+synch+data */
    //0x88, 0x01, /* wMaxPacketSize(0x0188): 392(49 samples * 4 bytes * 2 channels) */
    0x08, 0x00, /* wMaxPacketSize(0x0008): 8(8 samples * 1 bytes * 1 channel) */
    0x01,       /* bInterval(0x01): 2^x ms */


    /* Class-Specific AS IsochronousAudio Data Endpoint Descriptor(4.10.1.2) */
    0x08,       /* bLength(8) */
    0x25,       /* bDescriptorType(0x25): CS_ENDPOINT */
    0x01,       /* bDescriptorSubtype(0x01): EP_GENERAL */
    0x00,       /* bmAttributes(0x00): MaxPacketsOnly = FALSE */
    0x00,       /* bmControls(0x00) */
    0x00,       /* bLockDelayUnits(0x00) */
    0x00, 0x00, /* wLockDelay(0x0000) */

};
/*
 * Configuration Descriptor wrapper.
 */
static const USBDescriptor audio_configuration_descriptor = {
  sizeof audio_configuration_descriptor_data,
  audio_configuration_descriptor_data
};

/*
 * Endpoint Initialization
 */



void dataReceived(USBDriver *usbp, usbep_t ep) {
	(void) usbp;
	(void) ep;
// exit on USB reset
	chThdSleep(100);
	palTogglePad(GPIOD, GPIOD_LED6);

	chSysLockFromIsr();
	usbPrepareReceive(usbp, 1, receiveBuf,8);
	usbStartReceiveI(usbp, 1);
	chSysUnlockFromIsr();
}


static USBOutEndpointState ep1outstate;

static const USBEndpointConfig ep1config = {
		USB_EP_MODE_TYPE_ISOC,
		NULL,
		NULL,
		dataReceived,
		0x0000,
		8,
		NULL,
		&ep1outstate,
		0,
		NULL
};

/*
 * U.S. English language identifier.
 */
static const uint8_t audio_string0[] = {
  USB_DESC_BYTE(4),                     /* bLength.                         */
  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
  USB_DESC_WORD(0x0409)                 /* wLANGID (U.S. English).          */
};

/*
 * Vendor string.
 */
static const uint8_t audio_string1[] = {
	USB_DESC_BYTE(38),                    /* bLength.                         */
	USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
	'S', 0,
	'T', 0,
	'M', 0,
	'i', 0,
	'c', 0,
	'r', 0,
	'o', 0,
	'e', 0,
	'l', 0,
	'e', 0,
	'c', 0,
	't', 0,
	'r', 0,
	'o', 0,
	'n', 0,
	'i', 0,
	'c', 0,
	's', 0
};

/*
 * Device Description string.
 */
static const uint8_t audio_string2[] = {
  USB_DESC_BYTE(56),                    /* bLength.                         */
  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
  'C', 0,
  'h', 0,
  'i', 0,
  'b', 0,
  'i', 0,
  'O', 0,
  'S', 0,
  '/', 0,
  'R', 0,
  'T', 0,
  ' ', 0,
  'V', 0,
  'i', 0,
  'r', 0,
  't', 0,
  'u', 0,
  'a', 0,
  'l', 0,
  ' ', 0,
  'C', 0,
  'O', 0,
  'M', 0,
  ' ', 0,
  'P', 0,
  'o', 0,
  'r', 0,
  't', 0
};

/*
 * Serial Number string.
 */
static const uint8_t audio_string3[] = {
  USB_DESC_BYTE(8),                     /* bLength.                         */
  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
  '0' + CH_KERNEL_MAJOR, 0,
  '0' + CH_KERNEL_MINOR, 0,
  '0' + CH_KERNEL_PATCH, 0
};


/*
 * Strings wrappers array.
 */
static const USBDescriptor audio_strings[] = {
  {sizeof audio_string0, audio_string0},
  {sizeof audio_string1, audio_string1},
  {sizeof audio_string2, audio_string2},
  {sizeof audio_string3, audio_string3},
};









    